<template>
  <NMenu
    v-model:value="activeKey"
    :options="menus"
    mode="vertical"
    :collapsed="collapsed"
    :collapsed-width="64"
    :collapsed-icon-size="20"
    :indent="24"
    :width="300"
    :expanded-keys="openKeys"
    :value="getSelectedKeys"
    @update:value="clickMenuItem"
    @update:expanded-keys="menuExpanded"
  />
</template>

<script>
import { defineComponent, ref, onMounted, reactive, computed, watch, toRefs, unref, h } from "vue";
import { useRoute, useRouter } from "vue-router";
import { useState } from "@store/hock/useProperty";
import { NMenu, NIcon } from "naive-ui";

import {
  BookOutline,
  ChatbubbleEllipsesOutline,
  CloudDownloadOutline,
  AccessibilityOutline,
  Aperture,
  AppsOutline,
} from "@vicons/ionicons5"; // https://www.xicons.org/#/zh-CN

function renderIcon(icon) {
  return () => h(NIcon, null, { default: () => h(icon) });
}
/**
 * @description: 构造tree的加载数据
 * @param {*} arr
 * @param {*} paraentName
 * @author: zhj1214
 */
function createListData(arr, paraentName = "") {
  const arrIcon = [BookOutline, ChatbubbleEllipsesOutline, CloudDownloadOutline, AccessibilityOutline, Aperture, AppsOutline];
  const subs = [];
  arr.forEach(rout => {
    if (rout.children && rout.children.length > 0) {
      var children = createListData(rout.children, rout.name) || [];
    }
    const icon = arrIcon[Math.round(Math.random() * (arrIcon.length - 1))];

    subs.push({
      ...rout,
      key: `${paraentName}${paraentName ? "-" : ""}${rout.name}`,
      label: rout.meta.title || "标题",
      icon: renderIcon(icon),
      children,
    });
  });
  return subs;
}

export default defineComponent({
  components: {
    NMenu,
  },
  props: {
    collapsed: {
      // 侧边栏菜单是否收起
      type: Boolean,
    },
    // 位置
    location: {
      type: String,
      default: "left",
    },
  },
  emits: ["update:collapsed"],
  setup() {
    // 当前路由
    const currentRoute = useRoute();
    const router = useRouter();
    const routerState = useState("permission", ["addRouters"]);
    const routers = routerState.addRouters.value[0].children;
    console.log("原始路由列表", routerState.addRouters.value);

    const menus = ref([]);
    const selectedKeys = ref(currentRoute.name);
    const headerMenuSelectKey = ref("");

    // 获取当前打开的子菜单
    const { matched } = currentRoute;

    const getOpenKeys = matched && matched.length ? matched.map(item => item.name) : [];

    const state = reactive({
      openKeys: getOpenKeys,
    });

    const getSelectedKeys = computed(() => {
      return unref(selectedKeys);
    });

    // 跟随页面路由变化，切换菜单选中状态
    watch(
      () => routers,
      () => {
        updateMenu();
        state.openKeys = currentRoute.matched.map(item => item.name);
        const activeMenu = currentRoute.meta?.activeMenu || "";
        selectedKeys.value = activeMenu || currentRoute.name;
      }
    );

    function updateMenu() {
      const routersList = createListData(routers);
      menus.value = routersList;
    }

    // 点击菜单
    function clickMenuItem(key, item) {
      console.info(`[onUpdate:value]: ${JSON.stringify(key)}`);
      console.info(`[onUpdate:value]: ${JSON.stringify(item)}`);

      // const d = {
      //   id: 3,
      //   path: "https://www.baidu.com/",
      //   name: "monitor",
      //   meta: { title: "监控页（外部）", target: "_blank", permission: "monitor" },
      //   key: "dashboard-monitor",
      //   label: "监控页（外部）",
      // };

      if (/http(s)?:/.test(item.path)) {
        window.open(key, item.meta.target || "_blank");
      } else {
        router.push({ path: item.path });
      }
    }

    // 展开菜单
    function menuExpanded(openKeys) {
      if (!openKeys) return;
      const latestOpenKey = openKeys.find(key => state.openKeys.indexOf(key) === -1);
      const isExistChildren = findChildrenLen(latestOpenKey);
      state.openKeys = isExistChildren ? (latestOpenKey ? [latestOpenKey] : []) : openKeys;
    }

    // 查找是否存在子路由
    function findChildrenLen(key) {
      if (!key) return false;
      const subRouteChildren = [];
      for (const { children, key } of unref(menus)) {
        if (children && children.length) {
          subRouteChildren.push(key);
        }
      }
      return subRouteChildren.includes(key);
    }

    onMounted(() => {
      updateMenu();
    });

    return {
      activeKey: ref(null),
      ...toRefs(state),
      menus,
      selectedKeys,
      headerMenuSelectKey,
      getSelectedKeys,
      clickMenuItem,
      menuExpanded,
    };
  },
});
</script>
